package ua.edu.nuos.jeetraining2012.cms.entity;

import ua.edu.nuos.jeetraining2012.cms.util.validation.Email;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * EntityBean of user table.
 * <p/>
 * Define Entity for user table. Available fields:
 * <table>
 * <thead>
 * <tr>
 * <th>field name</th>
 * <th>descriptions</th>
 * <th>constraints</th>
 * </tr>
 * </thead>
 * <tbody>
 * <tr>
 * <td>id</td>
 * <td>Internal user id</td>
 * <td>Primary key, not null, auto-incremental.</td>
 * </tr>
 * <tr>
 * <td>email</td>
 * <td>User's email.</td>
 * <td>not null</td>
 * </tr>
 * <tr>
 * <td>name</td>
 * <td>User's first and last names.</td>
 * <td>Not null.</td>
 * </tr>
 * <tr>
 * <td>role</td>
 * <td>User's role. Possible role definitions see at {@link ua.edu.nuos.jeetraining2012.cms.dto.predefined.StandardUserRoles}</td>
 * <td>Not null.</td>
 * </tr>
 * <tr>
 * <td>status</td>
 * <td>User's current status. Possible statuses see at {@link ua.edu.nuos.jeetraining2012.cms.dto.predefined.StandardUserStatuses}</td>
 * <td>Not null.</td>
 * </tr>
 * </tbody>
 * </table>
 *
 * @author Victor N. Ganichev victor.ganichev@gmail.com
 * @version 1.0 Date: 23.04.13 Time: 22:21
 * @since 1.0
 */
@Entity
@Table(name = "users")
public class UserEntity implements Serializable {

    /**
     * Define user id as primary key, auto-incremental value. Not null.
     */
    @Id
    @Column(
            name = "id",
            nullable = false,
            insertable = true,
            updatable = true,
            length = 64
    )
    @NotNull(message = "Id can't be empty")
    @Size(min = 1, max = 64, message = "Max length is 64 characters long")
    private String id;

    /**
     * Define user email address. Can't be null.
     */
    @Column(
            name = "email",
            nullable = false,
            insertable = true,
            updatable = true,
            length = 128
    )
    @Basic(optional = false)
    @Email(message = "Value must be valid email address")
    private String email;

    /**
     * Define user name. Concatenated firstname and lastname. Can't be null.
     */
    @Column(
            name = "name",
            nullable = false,
            insertable = true,
            updatable = true,
            length = 256
    )
    @Basic(optional = false)
    @NotNull(message = "Name can't be empty")
    @Size(min = 1, max = 256, message = "Max length is 265 characters")
    private String name;

    /**
     * Define user roles according to {@link ua.edu.nuos.jeetraining2012.cms.dto.predefined.StandardUserRoles} lists.
     */
    @Column(
            name = "role",
            nullable = false,
            insertable = true,
            updatable = true,
            length = 15
    )
    @Basic(optional = false)
    @NotNull(message = "role can't be empty")
    @Size(min = 1, max = 15)
    private String role;

    /**
     * Define possible user statuses, according to {@link ua.edu.nuos.jeetraining2012.cms.dto.predefined.StandardUserStatuses} lists.
     */
    @Column(
            name = "status",
            nullable = false,
            insertable = true,
            updatable = true,
            length = 15
    )
    @NotNull(message = "status can't be empty")
    @Size(min = 1, max = 15)
    private String status;

    @Column(
            name = "registration_date",
            nullable = true,
            insertable = true,
            updatable = false,
            columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
    )
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date registrationTimeStamp;

    @Column(name = "svn_password", nullable=true)
    @Basic(optional=true)
    private String svnPassword;

    /**
     * Mapping to courses.
     */
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "userId", orphanRemoval = true)
    private List<UsersToCourseEntity> courses;


    @PrePersist
    private void onPrePersist() {
        this.registrationTimeStamp = new Date();
    }

    // Default constructor
    public UserEntity() {}

    // Getters & Setters
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Date getRegistrationTimeStamp() {
        return registrationTimeStamp;
    }

    public void setRegistrationTimeStamp(Date registrationTimeStamp) {
        this.registrationTimeStamp = registrationTimeStamp;
    }

    public String getSvnPassword() {
        return svnPassword;
    }

    public void setSvnPassword(String svnPassword) {
        this.svnPassword = svnPassword;
    }

    // Overrides

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserEntity that = (UserEntity) o;

        if (id != null ? !id.equals(that.id) : that.id != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return id != null ? id.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "UserEntityBean {" +
                "id:" + id +
                ", email:'" + email + '\'' +
                ", name:'" + name + '\'' +
                ", role:" + role +
                ", status:" + status +
                '}';
    }
}
